#include "hc_sr04.h"

static GPIO_InitTypeDef  GPIO_InitStructure;

// 初始化超声波模块（Trig:PB6输出	Echo:PE6输入）
void sr04_Init(void)
{
	// 1.配置GPIO	
	/* 1.打开外设时钟(根据需求再开启，节省功耗) */
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOE, ENABLE);
	
	/* 2.配置GPIO */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;	// GPIO引脚编号
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;		// 模式：输出模式
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;		// 类型：推挽
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	// 输出速率：跟功耗相关
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;	// 无上下拉
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;	// GPIO引脚编号
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;		// 模式：输入模式
	GPIO_Init(GPIOE, &GPIO_InitStructure);
	
	// 2.给Trig触发引脚一个初始化电平（低电平）
	GPIO_ResetBits(GPIOB, GPIO_Pin_6);
}

// 获取当前距离（合法数据：20mm ~ 4000mm）
int32_t sr04_get_distance(void)
{
	uint32_t t;
	
	// 1.给Trig 10us的高电平（触发信号）
	Trig = 1;
	delay_us(10);
	Trig = 0;
	
	// 2.循环等待Echo引脚为高电平
	t=0;
	while(!Echo)
	{
		delay_us(1);
		t++;
		
		//超时处理（1s超时）
		if(t >= 1000000)
			return -1; 
	}
	
	// 3.当Echo出现高电平，开始计算高电平时间
	t=0;
	while(Echo)
	{
		delay_us(9);
		t++;
		
		//超时处理（9s超时）
		if(t >= 1000000)
			return -2;
	}
	
	// 4.根据时间，算出路程，距离=路程/2
	return t*3/2;
}
